/*
** ---> This Test State is testing the following behaviours
** ---> Seek - Face - Flee - LookWhereYoureGoing - Wander
**
** ---> Louie
*/

#include "TestState2.h"
#include "Graphics.h"
#include "Timer.h"
#include "MyGL.h"
#include "Game.h"
#include "Error.h"
#include "Mesh.h"
#include "AssetManager.h"
#include "StringUtility.h"
#include "Texture.h"
#include "SteeringOutput.h"
#include <vector>
#include <SDL_events.h>
#include <iostream>

#define WORLD_SIZE	20
#define GRID_SIZE	5

#define WORLD_WRAP(var) \
    if (var < -WORLD_SIZE) var = WORLD_SIZE; \
    else if (var > WORLD_SIZE) var = -WORLD_SIZE;

TestState2::TestState2()
{
	m_hash		= Engine::Hash(GetName());
	m_target	= 0;
}

bool ts2 = Engine::TheGame::Instance() ->RegisterGameState(TheTestState2::Instance());

void TestState2::OnKeyboardEvent(const SDL_KeyboardEvent& k)
{
	if(k.keysym.sym == SDLK_ESCAPE) 
	{
		Engine::TheGame::Instance() ->SetCurrentGameState(nullptr);
	}

	//
	// ---> camera movement
	//
	float s = 8;
	switch(k.type)
	{
	case SDL_KEYDOWN:
		if(k.keysym.sym == SDLK_w)
			TheGameCamera::Instance() 
				->SetVel(Engine::Vec3(0,0,-s));
		if(k.keysym.sym == SDLK_s)
			TheGameCamera::Instance() 
				->SetVel(Engine::Vec3(0,0,s));
		if(k.keysym.sym == SDLK_a)
			TheGameCamera::Instance()
				->SetVel(Engine::Vec3(-s,0,0));
		if(k.keysym.sym == SDLK_d)
			TheGameCamera::Instance()
				->SetVel(Engine::Vec3(s,0,0));
		break;

	case SDL_KEYUP:
		TheGameCamera::Instance()
				->SetVel(Engine::Vec3(0,0,0));
		break;
	}
}

void TestState2::OnQuit()
{
	Engine::TheGame::Instance() ->SetCurrentGameState(nullptr);
};

void TestState2::Activate()
{
	GameState::Activate();

	// ---> Set up camera first
	//
	TheGameCamera::Instance()->SetPos(Engine::Vec3(0, 30, 20));
	TheGameCamera::Instance()->SetFoc(Engine::Vec3(0, 0, 0));

	// ---> setup path
	//
	m_path.InitPath(Engine::Vec3(10.0f, 0.0f, 10.0), Engine::Vec3(-10.0f, 0.0f, 0.0f));

	// ---> set unit properties
	//
	sb_fap		= new Engine::FollowPath;

	sb_fap		->SetPath(&m_path);
	sb_fap		->SetDistOffset(3.0f);

	sb_lwyg		= new Engine::LookWhereYoureGoing;
	sb_lwyg		->SetSlowRadius(0.1f);
	sb_lwyg		->SetTimeToTarget(0.3f);
	sb_lwyg		->SetTargetRadius(0.05f);

	m_target	= new Engine::Unit;

	m_target	->SetPos(Engine::Vec3(-9.0f, 0.0f, -5.0f));
	m_target	->SetScale(Engine::Vec3(1.0f, 0.5f, 1.0f));
	m_target	->SetMaxSpeed(35.0f);
	m_target	->SetMaxAngularVel(6.0f);
	m_target	->SetMaxAngularAcc(10.0f);

	m_target    ->Initialize();

	m_target	->AddSteeringBehaviour(Engine::WeightedSteeringBehaviour(sb_fap, 1.0f), m_target);
	m_target	->AddSteeringBehaviour(Engine::WeightedSteeringBehaviour(sb_lwyg, 1.0f), m_target); 
}

void TestState2::Update()
{
	TheGameCamera::Instance()->Update();

	//// ---> World wrap for wanderer
	////
	//float wx = m_wanderer ->GetPos().x;
	//float wz = m_wanderer ->GetPos().z;
	//
	//WORLD_WRAP(wx);
	//WORLD_WRAP(wz);

	//m_wanderer ->SetPos(Engine::Vec3(wx, m_wanderer ->GetPos().y, wz));

	//Engine::Vec3 d = m_path.MapPointToPath(m_target ->GetPos());
	//printf("%f \n", d);
	
	Engine::TheGame::Instance()->UpdateGameObjects();
}

void TestState2::Draw()
{
	m_path.DrawPath();

    // Draw grid
    glColor3f(0.8f, 0.8f, 0.8f);
    glBegin(GL_LINES);
    for (int i = -WORLD_SIZE; i <= WORLD_SIZE; i += GRID_SIZE)
	{
        glVertex3i(-WORLD_SIZE, -1, i);
        glVertex3i(WORLD_SIZE, -1, i);

        glVertex3i(i, -1, WORLD_SIZE);
        glVertex3i(i, -1, -WORLD_SIZE);
    }
    glEnd();

	TheGameCamera::Instance()->Draw();
	Engine::TheGame::Instance()->DrawGameObjects();
}